package com.devicemantra.coordinate.ds.tests;
import com.devicemantra.coordinate.dataobjects.*;
import com.google.appengine.api.labs.taskqueue.*; 

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;

import javax.jdo.PersistenceManager;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.*;

import com.devicemantra.coordinate.dataobjects.CDepartmentFactory;
import com.devicemantra.coordinate.exceptions.operations.CDepartmentDoesNotExistsException;
import com.devicemantra.coordinate.interfaces.http.CHttpPost;
import com.devicemantra.coordinate.interfaces.sms.SMS;
import com.devicemantra.coordinate.interfaces.sms.SMSFactory;
import com.devicemantra.coordinate.util.CLogger;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.labs.taskqueue.QueueFactory;
import static com.google.appengine.api.labs.taskqueue.TaskOptions.Builder.*;



@SuppressWarnings("serial")
public class BatchProcessMessage extends HttpServlet 
{
	boolean mAllDepts = false; 
	boolean mAllEmirates = false;
	
	private boolean processMessage(List<CLocation> pListFrames , String pMessage)
	{
		boolean lIsSuccess = false;
		return lIsSuccess;
	}
	
	
	/* 
	 * TODO: All the code below has been copied from GetFrames.java 
	 * refactor this code into a seperate helper class and use it from 
	 * both the files rather than duplicating code here -11:35 am , 25th Nov, 2009, 
	 * 
	 * */

	public List<CLocation> getAllDeptsAllEmirates()
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.getFetchPlan().setMaxFetchDepth(3);
	    List<CLocation> lCFrameList = null;
	    javax.jdo.Query query = pm.newQuery(CLocation.class);
		/*query.setFilter("mDestinationFrameId == lCFrameId");
		query.setFilter("mIsRead == lIsTrue"); */
		//query.declareParameters("String lCFrameId, boolean lGiveReadMessages");
	    lCFrameList = (List<CLocation>) query.execute();
	    lCFrameList = (List<CLocation>)pm.detachCopyAll(lCFrameList);
	    System.out.println("Number of frames found  for " + lCFrameList.size());
		pm.close();
		return lCFrameList;
	}
	
	public List<CLocation> getAllDeptsParticularEmirate(String pEmirate)
	{
		 PersistenceManager pm = PMF.get().getPersistenceManager();
		 List<CLocation> lCFrameList = null;
		 pm.getFetchPlan().setMaxFetchDepth(3);
		 javax.jdo.Query query = pm.newQuery(CLocation.class, "mEmirate == pEmirate");
		 /*query.setFilter("mDestinationFrameId == lCFrameId");
		 query.setFilter("mIsRead == lIsTrue"); */
		 query.declareParameters("String pEmirate");
		 lCFrameList = (List<CLocation>) query.execute(pEmirate);
		 lCFrameList = (List<CLocation>)pm.detachCopyAll(lCFrameList);
		 //pm.retrieveAll(lCFrameList);
		 System.out.println("Number of frames found  for " + pEmirate + " is "  +  lCFrameList.size());
		 pm.close();
		 return lCFrameList;
		
	}
	
	public List<CLocation> getAllEmiratesParticularDept(String pDeptName)
	{
		CDepartment lDept = null;
		try {
			lDept = CDepartmentFactory.getDepartment(pDeptName);
		} catch (CDepartmentDoesNotExistsException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		List<CLocation> lCFrameList = lDept.getLocations();
		System.out.println("Number of frames found  for " + pDeptName + " is "  +  lCFrameList.size());
		return lCFrameList;
		
	}
	
	public List<CLocation> getParticularDeptForParticularEmirate(String lDept, String lEmirate)
	{
		List<CLocation> lFrameList = getAllDeptsParticularEmirate(lEmirate);
		System.out.println("Number of frames for Emirate is " + lEmirate + " " + lFrameList.size());
		System.out.println("Printing retreived list now");
		printList(lFrameList);
		int lLengthOfList = lFrameList.size();
		List<CLocation> lNewFrameList = new ArrayList<CLocation>();
		for(int lCounter = 0; lCounter < lLengthOfList; lCounter++ )
		{
			CLocation lCFrame = lFrameList.get(lCounter);
			System.out.println("List size is " + lFrameList.size());
			System.out.println("Checking department " + lCFrame.getOwningDepartment().getDepartmentName() + " with " + lDept);
			if(lCFrame.getOwningDepartment().getDepartmentName().equals(lDept))
			{
				System.out.println("Checking  dept - " + lCFrame.getOwningDepartment().getDepartmentName());
				lNewFrameList.add(lCFrame);
				continue;
			}
			else
			{
				System.out.println("Removing dept - " + lCFrame.getOwningDepartment().getDepartmentName());
				//lFrameList.remove(lCounter);
			}
		}
		System.out.println("Returning list of size " + lFrameList.size());
		return lNewFrameList;
	}
	
	private List<CLocation> getLocationList(String pDeptName, String pEmirate)
	{
		List<CLocation> lCFrameList = null;
		if(pDeptName.equals("ALL") && pEmirate.equals("ALL"))
		{
			/* Request is for all the frames from different depts in all the states */
			lCFrameList = getAllDeptsAllEmirates();
			System.out.println("ALL Departments ALL Emirates");
		}
		
		if(pDeptName.equals("ALL") && !(pEmirate.equals("ALL")))
		{
			/* Request is for all the frames from different depts in a particular state */
			lCFrameList = getAllDeptsParticularEmirate(pEmirate);
			System.out.println("ALL Departments Particular Emirate " + pEmirate);
		}
		
		if( !(pDeptName.equals("ALL")) && pEmirate.equals("ALL"))
		{
			/* Request is for all the frames from different depts in a particular state */
			lCFrameList =  getAllEmiratesParticularDept(pDeptName);
			System.out.println("ALL Emirate Particular Department " + pDeptName);
		}
		
		if( !(pDeptName.equals("ALL")) && !(pEmirate.equals("ALL")) )
		{
			/* Request is for all the frames from different depts in a particular state */
			System.out.println("Callingg Particular Emirate Particular Department " + pDeptName + " " + pEmirate);
			lCFrameList = getParticularDeptForParticularEmirate(pDeptName, pEmirate);
			printList(lCFrameList);
			System.out.println("Particular Emirate Particular Department " + pDeptName);
		}
		
		//printList(lCFrameList);
		return lCFrameList;
	}
	
	public List<CContact> getAllContactsForLocation(String pLocationId)
	{
		PersistenceManager pm = PMF.get().getPersistenceManager();
		List<CContact> lContactList = null;
		pm.getFetchPlan().setMaxFetchDepth(3);
		javax.jdo.Query query = pm.newQuery(CContact.class, "mLocationId == pLocationId");
		 /*query.setFilter("mDestinationFrameId == lCFrameId");
		 query.setFilter("mIsRead == lIsTrue"); */
		 query.declareParameters("String pLocationId");
		 lContactList = (List<CContact>) query.execute(pLocationId);
		 lContactList = (List<CContact>)pm.detachCopyAll(lContactList);
		 //pm.retrieveAll(lCFrameList);
		 System.out.println("Number of contacts found  for " + pLocationId + " is "  +  lContactList.size());
		 pm.close();
		 return lContactList;
		
	}
	
	public void sendBulkSMS(List<CContact> pContactList, String pMessage)
	{
		CContact lContact = null;
		System.out.println("SMSList is " + pContactList.size());
		for(int lCounter = 0; lCounter < pContactList.size(); lCounter++ )
		{
			
			/* Code to send SMS to a predefined number */
			lContact = pContactList.get(lCounter);
			System.out.println("Contact name " + lContact.getContactName());
			SMS lNewSMS = SMSFactory.creatNewSMS();
			//lNewSMS.setMobileNumber("971559266628");
			lNewSMS.setMobileNumber(lContact.getCoordMobileId());
			lNewSMS.setMessage(pMessage);
			CHttpPost lHttpPost = new CHttpPost();
			String lXmlSMSMessage = SMSFactory.getSmsInXml(lNewSMS);
			lHttpPost.send(lXmlSMSMessage);
			System.out.println("Sending SMS to " + lNewSMS.getMobileNumber());
			
		}
		
	}
	
	public void printList(List<CLocation> pFrameList)
	{
		for(int lCounter = 0; lCounter < pFrameList.size(); lCounter++)
		{
			System.out.println("-------------------------");
			System.out.println("Frame id is " + pFrameList.get(lCounter).getLocationId());
			System.out.println("Frame department is " + pFrameList.get(lCounter).getOwningDepartment().getDepartmentName());
			System.out.println("-------------------------");
		}
	}
	
	
	
	
	public void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws IOException 
	{
		System.out.println("/BatchProcessMessage called now ");
		String lMessage = req.getParameter("message");
		String lDeptName = req.getParameter("dept_name");
		String lEmirateName = req.getParameter("emirate_name");
				
		System.out.println("Department is " + lDeptName);
		System.out.println("Emirate id is " + lEmirateName);
		System.out.println("Message is " + lMessage);
		
		/* Test code for testing queue API */
		/*Queue queue = (Queue) QueueFactory.getDefaultQueue();
		queue.add(url("/CSMSTask").param("key", "Amith Nambiar"));	
		System.out.println("Added task to the queue"); */
		
		
		/* Code to send SMS to a predefined number */
		//SMS lNewSMS = SMSFactory.creatNewSMS();
		//lNewSMS.setMobileNumber("971559266628");
		/*lNewSMS.setMobileNumber("971501325042");
		lNewSMS.setMessage(lMessage);
		CHttpPost lHttpPost = new CHttpPost();
		String lXmlSMSMessage = SMSFactory.getSmsInXml(lNewSMS); */
		//lHttpPost.send(lXmlSMSMessage);
		
		
		/* Get the list of frames this message will be delivered to */
		List<CLocation> lListLocations = getLocationList(lDeptName,lEmirateName);
		System.out.println("Message delivered to " + lListLocations.size());
		printList(lListLocations);
		CLogger.log("Total Locations to be sent " + lListLocations.size());
		
		List<CMessage1> lListMessage = new ArrayList<CMessage1>(lListLocations.size());
		List<CContact> lMainListContacts = new ArrayList<CContact>(100);
		for( int lCounter =0; lCounter < lListLocations.size(); lCounter++)
		{
			CLocation lLocation = lListLocations.get(lCounter);
			List<CContact> lContactList = getAllContactsForLocation(lLocation.getLocationId());
			CLogger.log("Detectdd " + lContactList.size() + "for " + lLocation.getOwningDepartment().getDepartmentName());
			lMainListContacts.addAll(lContactList);
			CMessage1 lCMessage = new CMessage1();
			lCMessage.setLocationId(lLocation.getLocationId());
			lCMessage.setMessage(lMessage);
			lCMessage.setDate(new Date());
			lCMessage.markAsUnRead();
			lListMessage.add(lCMessage);
		}
		
		
		//sendBulkSMS(lMainListContacts,lMessage);
		PersistenceManager pm = PMF.get().getPersistenceManager();
		pm.makePersistentAll(lListMessage);
		pm.close();
		
		
		
		
	}
}
